package fr.gla.hibtracker.historique.bm;

import java.util.Date;
import java.util.HashSet;
import java.util.Set;

import fr.gla.hibtracker.historique.listener.DirtyUpdateListener;

/**
 * <p>
 * Classe persistante contenant l'ensemble des modifications réalisées lors d'un flush sur la session hibernate, dans un
 * but d'historisation.
 * </p>
 *
 * <p>
 * Une instance de <code>FlushModifications</code> contient <em>n</em> instance de {@link GroupeModifications}, qui
 * regroupe les {@link Modification} par entité persistante.
 * </p>
 *
 * <p>
 * Les <code>FlushModifications</code> sont enregistrées au moyen d'un observateur hibernate configurés sur le flush :
 * {@link DirtyUpdateListener}.
 * </p>
 *
 * @see DirtyUpdateListener
 */
public class FlushModifications {

    private Integer                     id;

    /**
     * Date à laquelle la modification a été effectuée.
     */
    private Date                        dateModification;

    /**
     * Login de l'utilisateur ayant effectué les modifications.
     */
    private String                      user;

    private Set<GroupeModifications<?>> groupesModifications = new HashSet<GroupeModifications<?>>();

    public FlushModifications() {
        super();
    }

    public FlushModifications(Date dateModification, String user) {
        super();
        this.dateModification = dateModification;
        this.user = user;
    }

    /**
     * @see java.lang.Object#equals(java.lang.Object)
     */
    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (!(obj instanceof FlushModifications)) {
            return false;
        }
        FlushModifications object = (FlushModifications) obj;
        if (getId() == null || object.getId() == null) {
            return false;
        }
        return getId().equals(object.getId());
    }

    /**
     * @see java.lang.Object#hashCode()
     */
    @Override
    public int hashCode() {
        if (getId() == null) {
            return super.hashCode();
        } else {
            return getId().hashCode();
        }
    }

    public Date getDateModification() {
        return dateModification;
    }

    public void setDateModification(Date dateModification) {
        this.dateModification = dateModification;
    }

    public Set<GroupeModifications<?>> getGroupesModifications() {
        return groupesModifications;
    }

    public void setGroupesModifications(Set<GroupeModifications<?>> groupesModifications) {
        this.groupesModifications = groupesModifications;
    }

    public boolean addGroupesModification(GroupeModifications<?> groupeModifications) {
        groupeModifications.setFlushModifications(this);
        return groupesModifications.add(groupeModifications);
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getUser() {
        return user;
    }

    public void setUser(String user) {
        this.user = user;
    }

    public GroupeModifications<?> getGroupeModifications(Object object) {
        for (GroupeModifications<?> groupeModifications : getGroupesModifications()) {
            if (groupeModifications.getObject().equals(object)) {
                return groupeModifications;
            }
        }
        return null;
    }

    @Override
    public String toString() {
        StringBuilder builder = new StringBuilder();
        builder.append("[").append(user).append("]");
        builder.append(dateModification);
        for (GroupeModifications<?> groupeModifications : getGroupesModifications()) {
            builder.append(groupeModifications + "\n");
        }
        return builder.toString();
    }
}
